package com.example.ssd4.view;

import com.example.ssd4.domain.Lesson;
import com.example.ssd4.domain.Student;
import com.example.ssd4.util.EditableTextFieldTableCell;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.util.converter.DefaultStringConverter;

import java.util.*;

public class TeacherDialog extends Application {
    private VBox mainVBox;
    private Stage thisStage;
    private Scene scene;
    private String account;
    private TableView<Lesson> allLessonsTable;
    private ObservableList<Lesson> allLessonsList;
    private TableView<Lesson> chosenLessonsTable;
    private ObservableList<Lesson> chosenLessonsList;
    private final Map<String, Tab> tabsMap = new HashMap<>();
    private final Map<String, TableView> tablesMap = new HashMap<>();
    private TabPane tabPane;
    private Button returnBtn;
    private Button searchBtn;
    private Button resetBtn;
    private Button infoBtn;
    private Button newBtn;
    private Button submitBtn;
    private TextField nameSearch;
    private TextField teacherSearch;
    private ComboBox<String> attributeCb;
    private CheckBox hideCb;
    private CheckBox conflictCb;
    private ComboBox<String> dayCb;
    private ComboBox<String> timeCb;

    @Override
    public void start(Stage stage) throws Exception {
        mainVBox = new VBox();
        scene = new Scene(mainVBox,817,550);
        LoginDialog.addGlobalShortcut(scene);
        thisStage = stage;

        initGraphic();
        initData();
        initAction();

        stage.setResizable(false);
        stage.setScene(scene);
        stage.show();
    }

    private void initData() {
    }

    private void initGraphic() {
        //title
        HBox titleHBox = new HBox();
        HBox titleLeft = new HBox();
        mainVBox.getChildren().add(titleHBox);

        Label label = new Label(" 本科教务系统");
        label.setFont(Font.font("微软雅黑", FontWeight.BOLD,25));
        Image image = new Image("file:src/main/resources/image/logo3_proc.jpg");
        ImageView imageView = new ImageView(image);
        titleLeft.getChildren().addAll(imageView,label);
        returnBtn = new Button("返回登录");
        returnBtn.setStyle(
                "-fx-pref-width: 100px;-fx-pref-height: 20px;"+
                        "-fx-background-color: #FF0060;"+
                        "-fx-border-radius: 60px;"+
                        "-fx-font-size: 10px;"+
                        "-fx-text-fill: WHITE;"+
                        "-fx-font-weight: bold;");

        titleHBox.setPadding(new Insets(0,10,0,10));
        titleHBox.setSpacing(430);
        titleHBox.setAlignment(Pos.CENTER_LEFT);
        titleHBox.getChildren().addAll(titleLeft,returnBtn);

        //tab
        tabPane = new TabPane();
        Tab lessonTab = new Tab("全部课程");
        Tab myTab = new Tab("我的课程");
        tabPane.getTabs().addAll(lessonTab,myTab);
        mainVBox.getChildren().add(tabPane);

        VBox lessonVBox = new VBox();
        VBox myVBox = new VBox();
        lessonTab.setContent(lessonVBox);
        myTab.setContent(myVBox);
        lessonTab.setClosable(false);
        myTab.setClosable(false);

        //lessonTab
        {
            allLessonsTable = new TableView<>();
            allLessonsList = FXCollections.observableArrayList();
            List<Lesson> lessons = Lesson.readFromLogFile("src\\main\\resources\\data\\lesson.log");
            allLessonsList.addAll(lessons);
            allLessonsTable.setItems(allLessonsList);

            initTable(allLessonsTable);
            lessonVBox.getChildren().add(allLessonsTable);

            //search
            GridPane gridPane = new GridPane();
            lessonVBox.getChildren().add(gridPane);
            gridPane.setHgap(10);
            gridPane.setVgap(10);

            nameSearch = new TextField();
            gridPane.add(new Label("课程名:"),0,0);
            gridPane.add(nameSearch,1,0);
            gridPane.setPadding(new Insets(10));

            Label placeHolder_1 = new Label("");
            placeHolder_1.setMinWidth(50);
            gridPane.add(placeHolder_1,2,0);
            Label placeHolder_2 = new Label("");
            placeHolder_2.setMinWidth(50);
            gridPane.add(placeHolder_2,5,0);

            teacherSearch = new TextField();
            gridPane.add(new Label("教师:"),3,0);
            gridPane.add(teacherSearch,4,0);

            attributeCb = new ComboBox<>();
            attributeCb.getItems().addAll("全部","选修","公选");
            attributeCb.getSelectionModel().select(0);
            gridPane.add(new Label("课程性质:"),6,0);
            gridPane.add(attributeCb,7,0);

            dayCb = new ComboBox<>();
            dayCb.getItems().addAll("全部星期","周一", "周二", "周三", "周四", "周五");
            dayCb.getSelectionModel().select(0);
            gridPane.add(new Label("星期:"),0,1);
            gridPane.add(dayCb,1,1);

            timeCb = new ComboBox<>();
            timeCb.getItems().addAll("全部节次","0102","0304","0506","0708","0910");
            timeCb.getSelectionModel().select(0);
            gridPane.add(new Label("节次:"),3,1);
            gridPane.add(timeCb,4,1);

            hideCb = new CheckBox();
            hideCb.setText("隐藏我授课的课程");
            GridPane.setColumnSpan(hideCb,2);
            gridPane.add(hideCb,6,1);

            conflictCb = new CheckBox();
            conflictCb.setText("隐藏时间冲突的课程");
            GridPane.setColumnSpan(conflictCb,2);
            gridPane.add(conflictCb,6,2);

            HBox buttonHBox = new HBox();
            buttonHBox.setSpacing(20);
            searchBtn = new Button("搜索");
            searchBtn.setGraphic(new ImageView("file:src/main/resources/image/search.png"));
            searchBtn.setStyle(
                    "-fx-pref-width: 60px;-fx-pref-height: 10px;"+
                            "-fx-background-color: #2020A0;"+
                            "-fx-border-radius: 60px;"+
                            "-fx-font-size: 10px;"+
                            "-fx-text-fill: WHITE;"+
                            "-fx-font-weight: bold;");
            resetBtn = new Button("重置");
            resetBtn.setGraphic(new ImageView("file:src/main/resources/image/reset.png"));
            resetBtn.setStyle(
                    "-fx-pref-width: 60px;-fx-pref-height: 10px;"+
                            "-fx-background-color: #6aaefc;"+
                            "-fx-border-radius: 60px;"+
                            "-fx-font-size: 10px;"+
                            "-fx-text-fill: BLACK;"+
                            "-fx-font-weight: bold;");
            buttonHBox.getChildren().addAll(searchBtn,resetBtn);
            GridPane.setColumnSpan(buttonHBox,2);
            gridPane.add(buttonHBox,0,2);
        }

        //chooseTab
        {
            chosenLessonsTable = new TableView<>();
            chosenLessonsList = FXCollections.observableArrayList();
            List<Lesson> lessons = Lesson.readFromLogFile("src\\main\\resources\\data\\teacher\\" + account + ".log");
            chosenLessonsList.addAll(lessons);
            chosenLessonsTable.setItems(chosenLessonsList);

            initTable(chosenLessonsTable);

            chosenLessonsTable.setRowFactory(tv -> {
                TableRow<Lesson> row = new TableRow<>();
                row.setOnMouseClicked(event -> {
                    if (!row.isEmpty() && event.getClickCount() == 2) {
                        Lesson clickedRow = row.getItem();
                        createTab(clickedRow);
                    }
                });
                return row;
            });

            chosenLessonsTable.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
            myVBox.getChildren().add(chosenLessonsTable);

            infoBtn = new Button("学生详情");
            infoBtn.setGraphic(new ImageView("file:src/main/resources/image/studentlist.png"));
            infoBtn.setStyle(
                    "-fx-pref-width: 120px;-fx-pref-height: 30px;"+
                            "-fx-border-radius: 60px;"+
                            "-fx-font-size: 15px;"+
                            "-fx-font-weight: bold;");
            submitBtn = new Button("提交成绩");
            submitBtn.setGraphic(new ImageView("file:src/main/resources/image/submit.png"));
            submitBtn.setStyle(
                    "-fx-pref-width: 120px;-fx-pref-height: 30px;"+
                            "-fx-border-radius: 60px;"+
                            "-fx-font-size: 15px;"+
                            "-fx-font-weight: bold;");
            newBtn = new Button("新建课程");
            newBtn.setGraphic(new ImageView("file:src/main/resources/image/new.png"));
            newBtn.setStyle(
                    "-fx-pref-width: 120px;-fx-pref-height: 30px;"+
                            "-fx-border-radius: 60px;"+
                            "-fx-font-size: 15px;"+
                            "-fx-font-weight: bold;");
            HBox buttonHBox = new HBox();
            buttonHBox.setPadding(new Insets(20));
            buttonHBox.setSpacing(50);
            buttonHBox.getChildren().addAll(infoBtn,submitBtn,newBtn);
            buttonHBox.setAlignment(Pos.CENTER);
            myVBox.getChildren().add(buttonHBox);
        }
    }

    private void initTable(TableView tableView){
        tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        TableColumn<Lesson, String> idColumn = new TableColumn<>("ID");
        TableColumn<Lesson, String> nameColumn = new TableColumn<>("Name");
        TableColumn<Lesson, String> timeColumn = new TableColumn<>("Time");
        TableColumn<Lesson, String> teacherColumn = new TableColumn<>("Teacher");
        TableColumn<Lesson, String> scoreColumn = new TableColumn<>("Score");
        TableColumn<Lesson, String> creditColumn = new TableColumn<>("Credit");
        TableColumn<Lesson, String> attributeColumn = new TableColumn<>("Attribute");
        TableColumn<Lesson, String> capacityColumn = new TableColumn<>("Capacity");

        idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
        timeColumn.setCellValueFactory(new PropertyValueFactory<>("time"));
        teacherColumn.setCellValueFactory(new PropertyValueFactory<>("teacher"));
        scoreColumn.setCellValueFactory(new PropertyValueFactory<>("score"));
        creditColumn.setCellValueFactory(new PropertyValueFactory<>("credit"));
        attributeColumn.setCellValueFactory(new PropertyValueFactory<>("attribute"));
        capacityColumn.setCellValueFactory(new PropertyValueFactory<>("capacity"));

        idColumn.setMinWidth(80);
        nameColumn.setMinWidth(180);
        timeColumn.setMinWidth(200);
        teacherColumn.setMinWidth(80);
        scoreColumn.setMinWidth(80);
        creditColumn.setMinWidth(50);
        attributeColumn.setMinWidth(50);
        capacityColumn.setMinWidth(50);

        // 将列添加到TableView
        tableView.getColumns().addAll(idColumn, nameColumn, timeColumn, teacherColumn, scoreColumn, creditColumn, attributeColumn, capacityColumn);
    }

    private void initAction() {
        nameSearch.setOnAction(actionEvent -> {
            teacherSearch.requestFocus();
        });
        teacherSearch.setOnAction(actionEvent -> {
            attributeCb.requestFocus();
            attributeCb.show();
        });
        attributeCb.setOnAction(actionEvent -> {
            dayCb.requestFocus();
            dayCb.show();
        });
        dayCb.setOnAction(actionEvent -> {
            timeCb.requestFocus();
            timeCb.show();
        });
        timeCb.setOnAction(actionEvent -> {
            hideCb.requestFocus();
        });
        hideCb.setOnAction(actionEvent -> {
            conflictCb.requestFocus();
        });
        conflictCb.setOnAction(actionEvent -> {
            searchBtn.requestFocus();
        });

        returnBtn.setOnAction(actionEvent -> {
            try {
                LoginDialog.thisStage.show();
                thisStage.close();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        searchBtn.setOnAction(actionEvent -> {
            String nameValue = nameSearch.getText().trim();
            String teacherValue = teacherSearch.getText().trim();
            String dayValue = dayCb.getValue();
            String attributeValue = attributeCb.getValue();
            String timeValue = timeCb.getValue();
            boolean hideValue = hideCb.isSelected();
            boolean conflictValue = conflictCb.isSelected();

            List<Lesson> result = Lesson.readFromLogFile("src\\main\\resources\\data\\lesson.log");
            if (!nameValue.isEmpty()) {
                result = Lesson.findLessonsByName(result, nameValue);
            }
            if (!teacherValue.isEmpty()) {
                result = Lesson.findLessonsByTeacher(result, teacherValue);
            }
            if (!dayValue.equals("全部星期")) {
                result = Lesson.findLessonsByDay(result, dayValue);
            }
            if (!attributeValue.equals("全部")) {
                result = Lesson.findLessonsByAttribute(result, attributeValue);
            }
            if (!timeValue.equals("全部节次")) {
                result = Lesson.findLessonsByTime(result, timeValue);
            }
            if (hideValue) {
                List<Lesson> alreadySelectedLessons = Lesson.readFromLogFile("src\\main\\resources\\data\\student\\" + account + ".log");
                result.removeIf(alreadySelectedLessons::contains);
            }
            if (conflictValue) {
                List<Lesson> alreadySelectedLessons = Lesson.readFromLogFile("src\\main\\resources\\data\\student\\" + account + ".log");
                result.removeIf(lesson -> alreadySelectedLessons.stream().anyMatch(selectedLesson -> Lesson.isTimeConflict(lesson, selectedLesson)));
            }

            allLessonsList.clear();
            allLessonsList.addAll(result);
        });

        resetBtn.setOnAction(actionEvent -> {
            nameSearch.setText("");
            teacherSearch.setText("");
            dayCb.getSelectionModel().select(0);
            attributeCb.getSelectionModel().select(0);
            timeCb.getSelectionModel().select(0);
        });

        infoBtn.setOnAction(actionEvent -> {
            Lesson selectedItem = chosenLessonsTable.getSelectionModel().getSelectedItem();
            if(selectedItem == null){
                chosenLessonsTable.requestFocus();
                return;
            }
            createTab(selectedItem);
        });

        submitBtn.setOnAction(actionEvent -> {
            Lesson selectedLesson = chosenLessonsTable.getSelectionModel().getSelectedItem();

            // 检查是否所有学生都有分数
            boolean allStudentsHaveScore = checkIfAllStudentsHaveScore(selectedLesson);

            if (allStudentsHaveScore) {
                if(selectedLesson.getScore().equals("已提交")){
                    Alert alert = new Alert(Alert.AlertType.INFORMATION);
                    alert.setTitle("提交成绩");
                    alert.setHeaderText("提交成绩：失败");
                    alert.setContentText("课程成绩已经提交");
                    alert.show();
                    return;
                }
                // 显示确认对话框
                Alert confirmAlert = new Alert(Alert.AlertType.CONFIRMATION);
                confirmAlert.setTitle("确认提交");
                confirmAlert.setHeaderText("确认提交成绩");
                confirmAlert.setContentText("您确定要提交该课程的成绩吗？");

                Optional<ButtonType> result = confirmAlert.showAndWait();

                if (result.isPresent() && result.get() == ButtonType.OK) {
                    // 用户确认提交，执行提交操作
                    Lesson.updateLessonScoreStatus("src\\main\\resources\\data\\lesson.log", selectedLesson.getId());
                    Lesson.updateLessonScoreStatus("src\\main\\resources\\data\\teacher\\" + account + ".log", selectedLesson.getId());
                    Platform.runLater(()->{
                        allLessonsList.clear();
                        allLessonsList.addAll(Lesson.readFromLogFile("src\\main\\resources\\data\\lesson.log"));
                        chosenLessonsList.clear();
                        chosenLessonsList.addAll(Lesson.readFromLogFile("src\\main\\resources\\data\\teacher\\" + account + ".log"));
                        tablesMap.get(selectedLesson.getId()).setEditable(false);
                    });

                    // 显示成功提示
                    Alert successAlert = new Alert(Alert.AlertType.INFORMATION);
                    successAlert.setTitle("提交成绩");
                    successAlert.setHeaderText("提交成绩：成功");
                    successAlert.setContentText("课程成绩已提交");
                    successAlert.showAndWait();
                }
            } else {
                // 存在学生没有分数，显示错误提示
                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                alert.setTitle("提交成绩");
                alert.setHeaderText("提交成绩：失败");
                alert.setContentText("课程学生成绩未录入完成");
                alert.showAndWait();
            }
        });

        newBtn.setOnAction(actionEvent -> {
            NewLessonDialog newLessonDialog = new NewLessonDialog();
            try {
                newLessonDialog.start(new Stage());
                newLessonDialog.initAccount(account,this);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
            if (event.getCode() == KeyCode.S && event.isControlDown()) {
                searchBtn.fire();
                event.consume();
            }
        });
        scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
            if (event.getCode() == KeyCode.R && event.isControlDown()) {
                resetBtn.fire();
                event.consume();
            }
        });
    }

    private boolean checkIfAllStudentsHaveScore(Lesson lesson) {
        List<Student> students = Student.readFromLogFile("src\\main\\resources\\data\\lesson\\" + lesson.getId() + ".log");
        if (students == null) {
            return false;
        }
        for (Student student : students) {
            if (student.getScore().equals("无记录")) {
                // 学生没有分数，返回 false
                return false;
            }
        }
        // 所有学生都有分数，返回 true
        return true;
    }

    private void createTab(Lesson lesson){

        // 遍历已有的Tab，检查是否已存在与该Lesson对应的Tab
        for (Tab existingTab : tabPane.getTabs()) {
            if (existingTab.getText().equals(lesson.getName())) {
                // 如果已存在，直接选中该Tab并返回
                tabPane.getSelectionModel().select(existingTab);
                return;
            }
        }

        if (tabsMap.containsKey(lesson.getId())) {
            Tab existingTab = tabsMap.get(lesson.getId());
            tabPane.getTabs().add(existingTab);
            tabPane.getSelectionModel().select(existingTab);
            return;
        }

        Tab tab = new Tab(lesson.getName());
        tabsMap.put(lesson.getId(), tab);
        tabPane.getTabs().add(tab);
        VBox tabVBox = new VBox();
        tab.setContent(tabVBox);

        TableView<Student> studentsTable = new TableView<>();
        tablesMap.put(lesson.getId(),studentsTable);
        ObservableList<Student> studentsList = FXCollections.observableArrayList();
        List<Student> students = Student.readFromLogFile("src\\main\\resources\\data\\lesson\\" + lesson.getId() + ".log");
        if (students != null){
            studentsList.addAll(students);
        }
        studentsTable.setItems(studentsList);
        studentsTable.setPlaceholder(new Label("暂无学生选课"));

        studentsTable.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        TableColumn<Student, String> idColumn = new TableColumn<>("ID");
        TableColumn<Student, String> nameColumn = new TableColumn<>("Name");
        TableColumn<Student, String> groupColumn = new TableColumn<>("Group");
        TableColumn<Student, String> scoreColumn = new TableColumn<>("Score");

        if(lesson.getScore().equals("无记录")){
            studentsTable.setEditable(true);
        }
        scoreColumn.setEditable(true);
        scoreColumn.setCellFactory(column -> new EditableTextFieldTableCell<>(new DefaultStringConverter()));

        scoreColumn.setOnEditCommit(event -> {
            int currentIndex = studentsTable.getSelectionModel().getSelectedIndex();
            Student student = studentsTable.getSelectionModel().getSelectedItem();
            Student.updateScoreByStudentId("src\\main\\resources\\data\\lesson\\" + lesson.getId() + ".log",student.getId(),event.getNewValue());
            studentsList.get(currentIndex).setScore(event.getNewValue());
            if (currentIndex < studentsTable.getItems().size() - 1) {
                // 移动到下一行并开始编辑同一列的单元格
                studentsTable.getSelectionModel().clearAndSelect(currentIndex + 1, scoreColumn);
                studentsTable.edit(currentIndex + 1, scoreColumn);
            }
        });

        idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
        groupColumn.setCellValueFactory(new PropertyValueFactory<>("group"));
        scoreColumn.setCellValueFactory(new PropertyValueFactory<>("score"));

        idColumn.setMinWidth(100);
        nameColumn.setMinWidth(100);
        groupColumn.setMinWidth(200);
        scoreColumn.setMinWidth(100);

        // 将列添加到TableView
        studentsTable.getColumns().addAll(idColumn,nameColumn,groupColumn,scoreColumn);
        tabVBox.getChildren().add(studentsTable);

        for (TableColumn tableColumn : studentsTable.getColumns()){
            if (tableColumn != scoreColumn){
                setCellStyle(tableColumn);
            }
        }

        // 选中该Tab
        tabPane.getSelectionModel().select(tab);
    }

    private void setCellStyle(TableColumn tableColumn){
        tableColumn.setCellFactory(column -> {
            TableCell<Student, String> cell = new TableCell<Student, String>() {
                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item == null || empty) {
                        setText(null);
                    } else {
                        setText(item);
                        setAlignment(Pos.CENTER); // 设置单元格内容居中对齐
                    }
                }
            };
            return cell;
        });
    }

    public void updateAddLesson(){
        List<Lesson> lessons = Lesson.readFromLogFile("src\\main\\resources\\data\\teacher\\" + account + ".log");
        chosenLessonsList.clear();
        chosenLessonsList.addAll(lessons);

        lessons = Lesson.readFromLogFile("src\\main\\resources\\data\\lesson.log");
        allLessonsList.clear();
        allLessonsList.addAll(lessons);
    }

    public void initAccount(String account){
        this.account = account;
    }
}